Release 10.1A: OpenEdge Development:
Progress 4GL Handbook


Applying events in your application

You have already seen cases where a procedure causes an event to fire “artificially” by using the APPLY statement. In the CustOrders procedure, each button trigger has to APPLY the VALUE-CHANGED event to the Order browse to get it to run the internal procedure to display related data for the Order, such as this code for the Next button trigger:

DO: 
  GET NEXT CustQuery. 
  IF AVAILABLE Customer THEN  
  DO: 
    DISPLAY {&FIELDS-IN-QUERY-CustQuery} 
        WITH FRAME CustQuery IN WINDOW CustWin. 
    {&OPEN-BROWSERS-IN-QUERY-CustQuery} 
    APPLY "VALUE-CHANGED" TO OrderBrowse. 
  END. 
END. 

The APPLY statement causes whatever trigger is currently active for the event and object to fire. Unlike the ON statement, you must place the name of the event in quotation marks in an APPLY statement, if it is a literal value. This makes it possible to APPLY the value of a character variable instead. In this way, you can define a CHARACTER variable, assign it a value of an event name during program execution, and then use that value in an APPLY statement, adding flexibility to your programming. For example:

DEFINE VARIABLE cEvent AS CHARACTER NO-UNDO. 
     . 
     . 
     . 
cEvent = “VALUE-CHANGED”. 
     . 
     . 
     . 
APPLY cEvent TO <some object>. 

By contrast, Progress must know the event for an ON statement at compile time to prepare the trigger properly. For this reason the event name can’t be a variable, so you can specify it with or without quotation marks in the ON statement.

As another example, here’s a little procedure that transfers keystrokes from one fill-in field to another:

DEFINE VARIABLE cFillFrom AS CHARACTER  NO-UNDO. 
DEFINE VARIABLE cFillTo   AS CHARACTER  NO-UNDO. 
ENABLE cFillFrom cFillto WITH FRAME fFrame. 
ON ANY-PRINTABLE OF cFillFrom 
     APPLY LAST-KEY TO cFillto. 
WAIT-FOR CLOSE OF THIS-PROCEDURE. 

The LAST-KEY keyword is a built-in function that returns the value of the last keystroke the user pressed. Every time you enter a letter into the first fill-in field, cFillFrom, the ANY-PRINTABLE trigger fires which, as its name suggests, responds to any printable character typed on the keyboard, and this trigger retrieves that keystroke and applies it to the other fill-in field, cFillTo. So you can apply not just the standard events but even keyboard characters to an object like a fill-in field, if is enabled for input. Figure 8–12 shows the effect of typing Text into cFillFrom.

Figure 8–12: Result of typing into cFillFrom

Using NO-APPLY to suppress default processing for an event

When you type a letter such as A in a field, it naturally appears in the field on the screen. This is called the default processing for the event. If there were a trigger ON “A” OF cFillTo, then you could APPLY that event to the fill-in field, the trigger would fire, and the letter would appear. This is the normal result of applying an event: both the default processing and any trigger on the event occur. However, some event-object pairs do not get Progress default processing using the APPLY statement. For example, applying the CHOOSE event programmatically to a button executes the trigger on that button but does not give focus to the button in the way that clicking it would.

As another twist to this relationship between events and their actions, consider the action on the object that initiates the event, not the one that receives it and does its default processing for the event. Sometimes you want only the trigger action on the target object to occur and not the default processing for the object that initiated the event. In this case, you can use the special RETURN NO-APPLY statement at the end of the trigger definition to suppress the default processing on the object that initiated it.

To suppress the default processing for an event in your test procedure:

  1. Add the RETURN NO-APPLY statement (along with the DO-END statements to turn the trigger into a block of code):
  2. DEFINE VARIABLE cFillFrom AS CHARACTER  NO-UNDO. 
    DEFINE VARIABLE cFillTo   AS CHARACTER  NO-UNDO. 
    ENABLE cFillFrom cFillto WITH FRAME fFrame. 
    ON ANY-PRINTABLE OF cFillFrom 
    DO: 
        APPLY LAST-KEY TO cFillto. 
        RETURN NO-APPLY. 
    END. 
    WAIT-FOR CLOSE OF THIS-PROCEDURE. 
    

  3. Run the procedure and type some text into cFillFrom:
  4. When you type, the keystrokes are applied to cFillTo, that is its default processing. But the RETURN NO-APPLY statement suppresses the default processing the cFillFrom, so it remains blank.

  5. Add this statement to the trigger:
  6. ON ANY-PRINTABLE OF cFillFrom 
    DO: 
        APPLY LAST-KEY TO cFillto. 
        APPLY '*' TO cFillFrom. 
        RETURN NO-APPLY. 
    END. 
    

  7. Run the procedure.You get asterisks in cFillFrom for each keystroke you type:

The trigger first applies the keystroke to the second fill-in, which causes the character to be displayed. It then applies the literal ‘*’ to the first fill-in, causing it to be displayed there. Finally, it does a RETURN NO-APPLY to suppress the display of the character you actually typed into the first fill-in. You could use this sort of code for a password field, for example.

Applying a nonstandard event

With the APPLY statement, you can actually send any event to any object that has a trigger for that event. Progress executes the trigger even if there is no default handling for the event associated with that object type. Thus, you can use this feature to extend the repertoire of developer events (predefined events with the names U1 through U10) to include any event not normally associated with an object. For example, you could apply CHOOSE to a fill-in field, which does not normally support that event.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095